#include "ohos_screen_capturer_wrap.h"
#include "rtc_base/logging.h"
#include "pc/peer_connection_factory.h"
#include "pc/peer_connection_factory_proxy.h"
#include "audio/audio_state.h"

namespace webrtc {

ScreenCapturerOhosWrap::ScreenCapturerOhosWrap(PeerConnectionFactoryInterface* pc_factory, rtc::Thread *worker_thread){
  screen_capture_ = std::make_unique<ScreenCapturerOhos>();
  pc_factory_ = pc_factory;
  worker_thread_ = worker_thread;
  RTC_LOG(LS_INFO) << "ScreenCapturerOhosWrap worker_thread_ :" << worker_thread_;
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    worker_thread_->BlockingCall([&] {
        external_audio_source_.reset(new ohoswebrtc::OHOSExternalAudioSourceImpl());
        webrtc::PeerConnectionFactoryProxyWithInternal<webrtc::PeerConnectionFactory>* factory =
                static_cast<webrtc::PeerConnectionFactoryProxyWithInternal<webrtc::PeerConnectionFactory>*>(pc_factory_);
        webrtc::internal::AudioState* audio_state = (webrtc::internal::AudioState*)(factory->internal()->media_engine()->voice().GetAudioState().get());
        audio_state->AddAudioSource(static_cast<webrtc::AudioMixer::Source*>(external_audio_source_.get()));
        screen_capture_->SetAudioSource(external_audio_source_.get());
    });
  }
}

ScreenCapturerOhosWrap::~ScreenCapturerOhosWrap(){
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    worker_thread_->BlockingCall([&] {
        webrtc::PeerConnectionFactoryProxyWithInternal<webrtc::PeerConnectionFactory>* factory =
                static_cast<webrtc::PeerConnectionFactoryProxyWithInternal<webrtc::PeerConnectionFactory>*>(pc_factory_);
        webrtc::internal::AudioState* audio_state = (webrtc::internal::AudioState*)(factory->internal()->media_engine()->voice().GetAudioState().get());
        audio_state->RemoveAudioSource(static_cast<webrtc::AudioMixer::Source*>(external_audio_source_.get()));
    });
  }
}

int ScreenCapturerOhosWrap::DidCaptureVideoFrame(const webrtc::VideoFrame& frame, int capture_width, int capture_height) {
  dataCallback_->OnFrame(frame);
  width_ = capture_width;
  height_ = capture_height;
  return 0;
}

void ScreenCapturerOhosWrap::OnCaptureError(int32_t error_code){
  RTC_LOG(LS_ERROR) << "ScreenCapturerOhosWrap OnCaptureError error code :" << error_code;
}

bool ScreenCapturerOhosWrap::Init(){
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    return worker_thread_->BlockingCall([&] {
        auto res = screen_capture_->Init();
        return res;
    });
  }
  return false;
}

bool ScreenCapturerOhosWrap::Start(const cricket::VideoFormat& capture_format){
  RTC_LOG(LS_ERROR) << "ScreenCapturerOhosWrap Start begin ";
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    return worker_thread_->BlockingCall([&] {
        if(screen_capture_->Start(capture_format) == webrtc::CS_FAILED){
            return false;
        }
        return true;
    });
  }
  return false;
}

void ScreenCapturerOhosWrap::Stop() {
  RTC_LOG(LS_ERROR) << "ScreenCapturerOhosWrap Stop begin ";
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    worker_thread_->BlockingCall([&] {
        screen_capture_->Stop();
    });
  }
}

void ScreenCapturerOhosWrap::RegisterCaptureDataCallback(rtc::VideoSinkInterface<webrtc::VideoFrame> *dataCallback) {
  RTC_LOG(LS_ERROR) << "ScreenCapturerOhosWrap RegisterCaptureDataCallback";
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    worker_thread_->BlockingCall([&] {
        screen_capture_->SetCallback(this);
        dataCallback_ = dataCallback;
    });
  }
}

void ScreenCapturerOhosWrap::SetFrameRotation(int rotation){
  RTC_LOG(LS_ERROR) << "ScreenCapturerOhosWrap SetFrameRotation " << rotation;
  RTC_DCHECK(worker_thread_);
  if (worker_thread_) {
    worker_thread_->BlockingCall([&] {
        screen_capture_->SetFrameRotation(rotation);
    });
  }
}

}
